<template>
  <div class="wise-table">
    <el-table
      v-loading="loading"
      :data="tableData"
      :summary-method="getSummaries"
      :show-summary="showSummary"
      border
      highlight-current-row
      @selection-change="handleSelectionChange"
      @sort-change="sortHandle"
    >
      <template v-for="(column, index) in columns">
        <el-table-column v-if="column.type == 'selection'" :key="index" type="selection" fixed width="50" />
        <el-table-column v-else-if="column.type == 'index'" :key="index" :label="column.label" type="index" fixed width="50" />
        <el-table-column
          v-else-if="column.type == 'slot'"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth ? column.minWidth : '150px'"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template slot-scope="scope">
            <slot :name="column.prop" :row="scope.row" />
          </template>
        </el-table-column>
        <el-table-column
          v-else-if="['year', 'month', 'date', 'week', 'datetime'].indexOf(column.type) != -1"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth ? column.minWidth : '150px'"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template v-if="scope.row[column.prop]" slot-scope="scope">
            {{ scope.row[column.prop] | dateFormat(column.format) }}
          </template>
        </el-table-column>
        <el-table-column
          v-else-if="column.type == 'file'"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template slot-scope="scope">
            <el-image
              style="width: 50px; height: 50px"
              :src="scope.row[column.prop] | imgPath"
              fit="cover"
              :preview-src-list="getSrcList(scope.row[column.prop])"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-else-if="column.type == 'area'"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template slot-scope="scope">
            <template v-for="item in column.objKeys" v-if="item.tableShow">
              {{ scope.row[item.field] }}
            </template>
          </template>
        </el-table-column>
        <el-table-column
          v-else-if="column.type == 'radio'"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth ? column.minWidth : '150px'"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template slot-scope="scope">
            <template v-if="column.dataDic">
              {{ setDictData(column.dataDic, scope.row[column.prop]) }}
            </template>
            <template v-else>
              {{ scope.row[column.prop] }}
            </template>
          </template>
        </el-table-column>
        <el-table-column
          v-else-if="column.type == 'render'"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template slot-scope="scope">
            <column-render :row="scope.row" :index="scope.$index" :render="column.render" />
          </template>
        </el-table-column>
        <el-table-column
          v-else-if="column.type == 'switch'"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template slot-scope="scope">
            <el-switch
              v-model="scope.row[column.prop]"
              :active-text="column.active"
              :inactive-text="column.inactive"
              :active-value="column.activeValue"
              :inactive-value="column.inactiveValue"
              @change="switchHandle($event, scope.row, column.url, column.prop)"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-else-if="column.type == 'handle'"
          :key="index"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth"
          :fixed="column.fixed"
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        >
          <template slot-scope="scope">
            <template v-for="handle in column.handle">
              <template v-if="typeof handle === 'string'">
                <el-button v-if="handle === 'edit'" type="primary" size="small" round @click.native.prevent="editHandle(scope.row)">
                  编辑
                </el-button>
                <el-button v-if="handle === 'view'" type="info" size="small" round @click.native.prevent="viewHandle(scope.row)">
                  查看
                </el-button>
                <el-button v-if="handle === 'delete'" type="danger" size="small" round @click.native.prevent="deleteHandle(scope.row)">
                  删除
                </el-button>

              </template>
              <template v-else>
                <el-button
                  v-if="handle.key === 'edit' && handle.fun(scope.row)"
                  type="primary"
                  size="small"
                  round
                  @click.native.prevent="editHandle(scope.row)"
                >
                  编辑
                </el-button>
                <el-button
                  v-if="handle.key === 'view' && handle.fun(scope.row)"
                  type="info"
                  size="small"
                  round
                  @click.native.prevent="viewHandle(scope.row)"
                >
                  查看
                </el-button>
                <el-button
                  v-if="handle.key === 'delete' && handle.fun(scope.row)"
                  type="danger"
                  size="small"
                  round
                  @click.native.prevent="deleteHandle(scope.row)"
                >
                  删除
                </el-button>
              </template>
            </template>
            <slot name="handle" :row="scope.row" />
          </template>
        </el-table-column>
        <el-table-column
          v-else
          :key="index"
          :prop="column.prop"
          :index="index"
          :column-key="column.columnKey"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth ? column.minWidth : '150px'"
          :fixed="column.fixed"
          show-overflow-tooltip
          :render-header="column.renderHeader"
          :sortable="column.sortable"
          :header-align="column.align"
        />
      </template>
    </el-table>
    <div class="page-block">
      <pagination :background="true" :total="ts" :page.sync="page.p" :limit.sync="page.ps" @pagination="getTableData" />
    </div>
  </div>
</template>

<script>
import ColumnRender from './columnRender'
import { postHandle } from '@/api'
import Pagination from '../../Pagination/index'
import { imgPath } from '../../../filters'
export default {
  name: 'WiseTable',
  components: { Pagination, ColumnRender },
  props: {
    columns: {
      type: Array,
      required: true
    },
    url: {
      type: String,
      default: ''
    },
    showSummary: {
      type: Boolean,
      default: false
    },
    summariesExcludeList: {
      type: Array,
      default: () => {
        return []
      }
    },
    search: {
      type: Object,
      default: () => {
        return null
      }
    },
    fields: {
      type: Array
    },
    filters: {
      type: Array
    },
    filterObj: {
      type: Object
    },
    tableRowClassNameFun: {
      type: Function
    }
  },
  data() {
    return {
      loading: false,
      tableData: [],
      ts: 0,
      sorts: [],
      page: {
        p: 1,
        ps: 10
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.getTableData()
    })
  },
  methods: {
    getTableData() {
      this.loading = true
      const req = {
        d: {
          fields: this.fields,
          filters: this.filters,
          page: this.page,
          search: this.search,
          sorts: this.sorts,
          retPage: true
        },
        obj: this.filterObj
      }
      postHandle(this.url, req).then(response => {
        this.tableData = response.result
        this.ts = response.page.ts
        this.loading = false
      })
    },
    switchHandle(val, row, url, params) {
      row[params] = val
      postHandle(url + row.id, { obj: row }).then(response => {
        this.getTableData()
        this.$message({
          type: 'success',
          message: '操作成功!'
        })
      })
    },
    refresh(page) {
      if (page) {
        this.page.p = page
      }
      this.getTableData()
    },
    editHandle(row) {
      this.$emit('on-edit', row)
    },
    viewHandle(row) {
      this.$emit('on-view', row)
    },
    deleteHandle(row) {
      this.$emit('on-delete', row)
    },
    setDictData(dataDic, value) {
      let label
      const options = require('../data/dataDictionary')[dataDic]
      if (options && options.length > 0) {
        const obj = options.find(item => item.value === value)
        if (obj) {
          label = obj.label
        }
      }
      return label
    },
    getSrcList(str) {
      let arr = []
      if (str) {
        arr = str.split(';')
      }
      return arr.map(item => imgPath(item))
    },
    tableRowClassName({ row, rowIndex }) {
      if (typeof this.tableRowClassNameFun === 'function') {
        return this.tableRowClassNameFun(row, rowIndex)
      }
      return ''
    },
    getSummaries(param) {
      const { columns, data } = param
      const sums = []
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '合计'
          return
        }
        if (this.summariesExcludeList.indexOf(column.property) !== -1) {
          sums[index] = ''
          return false
        }
        const values = data.map(item => Number(item[column.property]))
        if (!values.every(value => isNaN(value))) {
          sums[index] = values.reduce((prev, curr) => {
            const value = Number(curr)
            if (!isNaN(value)) {
              return prev + curr
            } else {
              return prev
            }
          }, 0)
        } else {
          sums[index] = ''
        }
      })

      return sums
    },
    sortHandle({ column, prop, order }) {
      if (order) {
        this.sorts = [{ field: prop, isDesc: order === 'descending' }]
      } else {
        this.sorts = []
      }
      this.getTableData()
    },
    handleSelectionChange(val) {
      this.$emit('selection-change', val)
    }
  }
}
</script>

<style>
.el-table .warning-row {
  background: #e6a23c;
}

.el-table .success-row {
  background: #f0f9eb;
}
</style>
